#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>

void failed(const char *fmt, ...) {
  char tmp[1024];
  va_list ap;

  va_start(ap, fmt);
  vsnprintf(tmp, sizeof(tmp), fmt, ap);
  va_end(ap);

  puts(tmp);
  printf("  LAST ERRNO=%d\n", errno);
  exit(1);
}

void create_read_and_write(const char* name) {
  static const char HELLO[5] = "HELLO";

  int fd = open(name, O_CREAT | O_WRONLY);  
  if (fd <= -1)
    failed("Failed to open %s.\n", name);

  if (write(fd, HELLO, 5) != 5)
    failed("Failed to write %s.\n", name);

  if (close(fd))
    failed("Failed to close %s.\n", name);

  fd = open(name, O_RDONLY);
  if (fd <= -1)
    failed("Failed to open %s.\n", name);

  char tmp[10];
  if (read(fd, tmp, 10) != 5)
    failed("Failed to read 5 bytes from %s.\n", name);
 
  if (strncmp(tmp, HELLO, 5))
    failed("Failed to read 'HELLO' from '%s'.\n", name);

  if (close(fd))
    failed("Failed to close %s.\n", name);

  struct stat s;
  if (stat(name, &s))
    failed("Failed to stat %s.\n", name);

  if (s.st_size != 5)
    failed("Failed to get correct length for stat of %s.\n", name);
}

void open_and_read_dir(const char* dirname, const char* appname) {
  DIR* dir = opendir(dirname);
  if (NULL == dir)
    failed("Failed to open directory '%s'.", dirname);

  struct dirent* d;
  int cnt = 0;
  while(d = readdir(dir)) {
    if (!strcmp(d->d_name, appname)) {
      printf("Found self: %s.\n", appname);
      if (closedir(dir))
        failed("Failed to close directory '%s'.", dirname);
      return;
    }
  }

  failed("Failed to find file: %s.\n", appname);
}

int main(int argc, char* argv[]) {
  create_read_and_write("test1.dat");
  open_and_read_dir(".", "test1.dat");
  return 0;
}
